package com.sl.au.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.sl.au.entity.Division;
import com.sl.au.entity.EventType;
import com.sl.au.entity.Hierarchy;
import com.sl.au.entity.Option;
import com.sl.au.entity.Part;
import com.sl.au.service.DivisionService;
import com.sl.au.service.EventTypeService;
import com.sl.au.service.HierarchyService;
import com.sl.au.service.OptionService;
import com.sl.au.service.PartService;
import com.sl.utils.MsgHelper;

@Controller
@RestController
@RequestMapping("/ui/doc")
public class DocMngController extends BaseController {

	@Autowired
	private OptionService optionService;
	@Autowired
	private PartService partService;
	@Autowired
	private DivisionService divisionService;
	@Autowired
	private HierarchyService hierarchyService;
	@Autowired
	private EventTypeService eventTypeService;

	/**
	 * 显示事件类型结构
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/initEventTypeTree", method = RequestMethod.GET)
	public Map<String, Object> initEventTypeTree(HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();
		List<EventType> node = eventTypeService.getAllNodes();
		List<Map<String, Object>> nodeMap = new ArrayList<Map<String, Object>>();

		nodeMap = eventTypeService.getNodeMap(node);

		map.put("code", 1);
		map.put("nodes", nodeMap);

		return map;
	}

	/**
	 * 显示组织结构
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/initHierarchyTree", method = RequestMethod.GET)
	public Map<String, Object> initHierarchyTree(HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();

		List<Hierarchy> node = hierarchyService.getAllNodes();
		List<Map<String, Object>> nodeMap = new ArrayList<Map<String, Object>>();

		nodeMap = hierarchyService.getNodeMap(node);

		map.put("code", 1);
		map.put("nodes", nodeMap);

		return map;
	}

	/**
	 * 显示区域树结构
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/initDivisionTree", method = RequestMethod.GET)
	public Map<String, Object> getAllNodes(HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();
		List<Division> node = divisionService.getAllNodes();
		List<Map<String, Object>> nodeMap = new ArrayList<Map<String, Object>>();
		nodeMap = divisionService.getNodeMap(node);
		map.put("code", 1);
		map.put("nodes", nodeMap);

		return map;
	}

	/**
	 * 显示部件类型树结构
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/initPartTree", method = RequestMethod.GET)
	public Map<String, Object> initPartTree(HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();
		List<Part> node = partService.getAllNodes();
		List<Map<String, Object>> nodeMap = new ArrayList<Map<String, Object>>();

		nodeMap = partService.getNodeMap(node);

		map.put("code", 1);
		map.put("nodes", nodeMap);

		return map;
	}

	@RequestMapping(value = "/saveEventTypeByExcel", method = RequestMethod.POST)
	public MsgHelper saveEventTypeByExcel(MultipartFile file) {
		int nowRow = 0;// 当前行
		if (isRightFile(file)) {
			// 将文件上传到指定的磁盘中
			String excelPath = this.getUploadFilePath(this.fileUploadPath, "excel/hierarchy", file);
			// 从磁盘中读取文件信息并上传到数据库中
			excelPath = this.fileUploadPath + excelPath;
			try {
				Workbook workbook = null;
				String fileName = file.getOriginalFilename();
				if (fileName.endsWith(".xls")) {// 处理低版本
					workbook = new HSSFWorkbook(new FileInputStream(new File(excelPath)));
				}
				if (fileName.endsWith(".xlsx")) {// 处理高版本
					workbook = new XSSFWorkbook(new FileInputStream(new File(excelPath)));
				}
				Sheet sheet = workbook.getSheetAt(0);
				int lastRowNum = sheet.getLastRowNum();

				for (int i = 1; i <= lastRowNum; i++) {// 遍历每一行
					nowRow = i;
					Row row = sheet.getRow(i);
					// 事件名称
					String eventName = row.getCell(0).getStringCellValue();
					// 事件编码
					Cell identifyCell = row.getCell(1);
					// public final static int CELL_TYPE_STRING = 1;
					// public final static int CELL_TYPE_NUMERIC = 0;
					int cellType = identifyCell.getCellType();// 要么文本 要么数字
					String eventIdentify = null;
					if (cellType == Cell.CELL_TYPE_STRING) {
						eventIdentify = identifyCell.getStringCellValue();
					} else {
						eventIdentify = ((Double) identifyCell.getNumericCellValue()).intValue() + "";
					}
					// 事件序号
					int eventOrder = ((Double) row.getCell(2).getNumericCellValue()).intValue();
					// 父级编号[导入一级部件时只有编号,没有名称]
					String parentId = row.getCell(3).getStringCellValue();
					parentId = super.getParentId(parentId);
					// 事件权重
					float eventWeight = ((Double) row.getCell(4).getNumericCellValue()).floatValue();
					// 处理时限
					float processLimit = ((Double) row.getCell(5).getNumericCellValue()).floatValue();
					// 接收时限
					float acceptLimit = ((Double) row.getCell(6).getNumericCellValue()).floatValue();
					// 首次奖励积分
					double firstRewardScore = row.getCell(7).getNumericCellValue();
					// 累计奖励积分
					double rewardScore = row.getCell(8).getNumericCellValue();
					// 备注
					String memo = row.getCell(9).getStringCellValue();
					// 组织层级
					String level = row.getCell(10).getStringCellValue();
					Option option = optionService.getRepository().findByGroupAndTitle("事件层级", level).get(0);
					// 编码位数限定
					Cell iLenCell = row.getCell(11);
					int iLen = 0;
					if (iLenCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
						iLen = (int) iLenCell.getNumericCellValue();
					} else {
						iLen = Integer.parseInt(iLenCell.getStringCellValue());
					}
					// 图标地址
					String addr = null;// row.getCell(12).getStringCellValue();
					// 保存
					if (!hasExistEventType(parentId, eventIdentify)) {
						if (iLen > eventIdentify.length() || iLen == eventIdentify.length()) {
							EventType e = new EventType();
							e.setAcceptLimit(acceptLimit);
							e.setEventIdentify(eventIdentify);
							e.setEventLevel(option);
							e.setEventName(eventName);
							e.setEventOrder(eventOrder);
							e.setEventParent(parentId);
							e.setEventShow(true);
							e.setEventWeight(eventWeight);
							e.setFirstRewardScore(firstRewardScore);
							e.setGridShow(true);
							e.setIconAddress(addr);
							e.setMemo(memo);
							e.setPartShow(true);
							e.setProcessLimit(processLimit);
							e.setRewardScore(rewardScore);
							e.setUserShow(true);
							eventTypeService.getRepository().save(e);
							eventTypeService.setEventTypeOrder(parentId);
						} else {
							return MsgHelper.failed().put("msg", "第 " + nowRow + " 行编码位数不对 ");
						}
					} else {
						return MsgHelper.failed().put("msg", "第 " + nowRow + " 行数据编码与已有数据编码冲突 ");
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				return MsgHelper.failed().put("msg", "第 " + nowRow + " 行数据错误 ");
			}
		}
		return MsgHelper.success();
	}

	@RequestMapping(value = "/saveHierarchyByExcel", method = RequestMethod.POST)
	public MsgHelper saveHierarchyByExcel(MultipartFile file) {
		int nowRow = 0;// 当前行
		if (isRightFile(file)) {
			// 将文件上传到指定的磁盘中
			String excelPath = this.getUploadFilePath(this.fileUploadPath, "excel/hierarchy", file);
			// 从磁盘中读取文件信息并上传到数据库中
			excelPath = this.fileUploadPath + excelPath;
			try {
				Workbook workbook = null;
				String fileName = file.getOriginalFilename();
				if (fileName.endsWith(".xls")) {// 处理低版本
					workbook = new HSSFWorkbook(new FileInputStream(new File(excelPath)));
				}
				if (fileName.endsWith(".xlsx")) {// 处理高版本
					workbook = new XSSFWorkbook(new FileInputStream(new File(excelPath)));
				}
				Sheet sheet = workbook.getSheetAt(0);
				int lastRowNum = sheet.getLastRowNum();

				for (int i = 1; i <= lastRowNum; i++) {// 遍历每一行
					nowRow = i;
					Row row = sheet.getRow(i);
					// 组织名称
					String groupName = row.getCell(0).getStringCellValue();
					// 组织编码
					Cell identifyCell = row.getCell(1);
					// public final static int CELL_TYPE_STRING = 1;
					// public final static int CELL_TYPE_NUMERIC = 0;
					int cellType = identifyCell.getCellType();// 要么文本 要么数字
					String groupIdentify = null;
					if (cellType == Cell.CELL_TYPE_STRING) {
						groupIdentify = identifyCell.getStringCellValue();
					} else {
						groupIdentify = ((Double) identifyCell.getNumericCellValue()).intValue() + "";
					}
					// 组织序号
					int groupOrder = ((Double) row.getCell(2).getNumericCellValue()).intValue();
					// 父级编号[导入一级部件时只有编号,没有名称]
					String parentId = row.getCell(3).getStringCellValue();
					parentId = super.getParentId(parentId);

					// 组织电话
					DecimalFormat df = new DecimalFormat("0");
					double sp = row.getCell(4).getNumericCellValue();
					String phone = df.format(sp) + "";

					// 组织基本考评分数
					float groupScore = ((Double) row.getCell(5).getNumericCellValue()).floatValue();
					// 组织基本考评权重
					float groupScoreWeight = ((Double) row.getCell(6).getNumericCellValue()).floatValue();
					// 组织层级
					String level = row.getCell(7).getStringCellValue();
					Option option = optionService.getRepository().findByGroupAndTitle("组织层级", level).get(0);

					// 图标地址
					String addr = null; // row.getCell(8).getStringCellValue();
					// 备注
					String memo = row.getCell(9).getStringCellValue();
					// 编码位数限定
					Cell iLenCell = row.getCell(10);
					int iLen = 0;
					if (iLenCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
						iLen = (int) iLenCell.getNumericCellValue();
					} else {
						iLen = Integer.parseInt(iLenCell.getStringCellValue());
					}

					// 保存
					if (!hasExistHierarchy(parentId, groupIdentify)) {
						// 层级下的value值限定了编码的长度
						if (iLen > groupIdentify.length() || iLen == groupIdentify.length()) {
							Hierarchy h = new Hierarchy();
							h.setEventShow(true);
							h.setGridShow(true);
							h.setGroupIdentify(groupIdentify);
							h.setGroupLevel(option);
							h.setGroupName(groupName);
							h.setGroupOrder(groupOrder);
							h.setGroupParent(parentId);
							h.setGroupScore(groupScore);
							h.setGroupScoreWeight(groupScoreWeight);
							h.setGroupTelphone(phone);
							h.setIconAddress(addr);
							h.setMemo(memo);
							h.setPartShow(true);
							h.setUserShow(true);
							hierarchyService.getRepository().save(h);
							hierarchyService.setHierarchyOrder(parentId);
						} else {
							return MsgHelper.failed().put("msg", "第 " + nowRow + " 行编码位数不对 ");
						}
					} else {
						return MsgHelper.failed().put("msg", "第 " + nowRow + " 行数据编码与已有数据编码冲突 ");
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				return MsgHelper.failed().put("msg", "第 " + nowRow + " 行数据错误 ");
			}
		}
		return MsgHelper.success();
	}

	@RequestMapping(value = "/saveDivisionByExcel", method = RequestMethod.POST)
	public MsgHelper saveDivisionByExcel(MultipartFile file) {
		int nowRow = 0;// 当前行
		if (isRightFile(file)) {
			// 将文件上传到指定的磁盘中
			String excelPath = this.getUploadFilePath(this.fileUploadPath, "excel/division", file);
			// 从磁盘中读取文件信息并上传到数据库中
			excelPath = this.fileUploadPath + excelPath;
			try {
				Workbook workbook = null;
				String fileName = file.getOriginalFilename();
				if (fileName.endsWith(".xls")) {// 处理低版本
					workbook = new HSSFWorkbook(new FileInputStream(new File(excelPath)));
				}
				if (fileName.endsWith(".xlsx")) {// 处理高版本
					workbook = new XSSFWorkbook(new FileInputStream(new File(excelPath)));
				}
				Sheet sheet = workbook.getSheetAt(0);
				int lastRowNum = sheet.getLastRowNum();

				for (int i = 1; i <= lastRowNum; i++) {// 遍历每一行
					nowRow = i;
					Row row = sheet.getRow(i);
					// 区域名称
					String divisionName = row.getCell(0).getStringCellValue();
					if (divisionName == null || "".equals(divisionName)) {
						continue;
					}
					// 区域编码
					Cell identifyCell = row.getCell(1);
					// public final static int CELL_TYPE_STRING = 1;
					// public final static int CELL_TYPE_NUMERIC = 0;
					int cellType = identifyCell.getCellType();// 要么文本 要么数字
					String divisionIdentify = null;
					if (cellType == Cell.CELL_TYPE_STRING) {
						divisionIdentify = identifyCell.getStringCellValue();
					} else {
						divisionIdentify = ((Double) identifyCell.getNumericCellValue()).intValue() + "";
					}
					// 区域序号
					int divisionOrder = ((Double) row.getCell(2).getNumericCellValue()).intValue();

					// 父级编号[导入一级部件时只有编号,没有名称]
					String parentId = row.getCell(3).getStringCellValue();
					parentId = super.getParentId(parentId);
					// 区域层级
					String level = row.getCell(4).getStringCellValue();
					Option option = optionService.getRepository().findByGroupAndTitle("区域层级", level).get(0);
					// 图标地址
					String addr = null; // row.getCell(5).getStringCellValue();
					// 备注
					String memo = row.getCell(6).getStringCellValue();
					// 编码位数限定
					Cell iLenCell = row.getCell(7);
					int iLen = 0;
					if (iLenCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
						iLen = (int) iLenCell.getNumericCellValue();
					} else {
						iLen = Integer.parseInt(iLenCell.getStringCellValue());
					}

					// 保存
					if (!hasExistDivision(parentId, divisionIdentify)) {
						// 层级下的value值限定了编码的长度
						if (iLen > divisionIdentify.length() || iLen == divisionIdentify.length()) {
							Division d = new Division();
							d.setDivisionIdentify(divisionIdentify);
							d.setDivisionLevel(option);
							d.setDivisionName(divisionName);
							d.setDivisionOrder(divisionOrder);
							d.setDivisionParent(parentId);
							d.setEventShow(true);
							d.setIconAddress(addr);
							d.setGridShow(true);
							d.setMemo(memo);
							d.setPartShow(true);
							d.setUserShow(true);
							divisionService.getRepository().save(d);
							divisionService.setDivisionOrder(parentId);
						} else {
							return MsgHelper.failed().put("msg", "第 " + nowRow + " 行编码位数不对 ");
						}
					} else {
						return MsgHelper.failed().put("msg", "第 " + nowRow + " 行数据编码与已有数据编码冲突 ");
					}

				}
			} catch (Exception e) {
				e.printStackTrace();
				return MsgHelper.failed().put("msg", "第 " + nowRow + " 行数据错误 ");
			}
		}
		return MsgHelper.success();
	}

	/**
	 * 批量上传之部件类型
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/savePartByExcel", method = RequestMethod.POST)
	public MsgHelper savePartByExcel(MultipartFile file) {

		int nowRow = 0;// 当前行
		if (isRightFile(file)) {
			// 将文件上传到指定的磁盘中
			String excelPath = this.getUploadFilePath(this.fileUploadPath, "excel/part", file);
			// 从磁盘中读取文件信息并上传到数据库中
			excelPath = this.fileUploadPath + excelPath;
			try {
				Workbook workbook = null;
				String fileName = file.getOriginalFilename();
				if (fileName.endsWith(".xls")) {// 处理低版本
					workbook = new HSSFWorkbook(new FileInputStream(new File(excelPath)));
				}
				if (fileName.endsWith(".xlsx")) {// 处理高版本
					workbook = new XSSFWorkbook(new FileInputStream(new File(excelPath)));
				}
				Sheet sheet = workbook.getSheetAt(0);
				int lastRowNum = sheet.getLastRowNum();

				for (int i = 1; i <= lastRowNum; i++) {// 遍历每一行
					nowRow = i;
					Row row = sheet.getRow(i);
					// 部件名称
					String partName = row.getCell(0).getStringCellValue();
					if ("".equals(partName) || partName == null) {
						continue;
					}
					// 部件编码
					Cell identifyCell = row.getCell(1);
					// public final static int CELL_TYPE_STRING = 1;
					// public final static int CELL_TYPE_NUMERIC = 0;
					int cellType = identifyCell.getCellType();// 要么文本 要么数字
					String partIdentify = null;
					if (cellType == Cell.CELL_TYPE_STRING) {
						partIdentify = identifyCell.getStringCellValue();
					} else {
						partIdentify = ((Double) identifyCell.getNumericCellValue()).intValue() + "";
					}

					// 部件顺序号
					int partOrder = ((Double) row.getCell(2).getNumericCellValue()).intValue();

					// 父级编号[导入一级部件时只有编号,没有名称]
					String parentId = row.getCell(3).getStringCellValue();
					parentId = super.getParentId(parentId);
					// 部件分类
					String title = row.getCell(4).getStringCellValue();
					Option type = optionService.getRepository().findByGroupAndTitle("部件类别", title).get(0);
					// 部件层级
					String level = row.getCell(5).getStringCellValue();
					Option option = optionService.getRepository().findByGroupAndTitle("部件层级", level).get(0);

					// 图标地址
					String addr = null; // row.getCell(6).getStringCellValue();
					// 编码字符限定个数
					Cell iLenCell = row.getCell(7);

					int iLen = 0;
					if (iLenCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
						iLen = (int) iLenCell.getNumericCellValue();
					} else {
						iLen = Integer.parseInt(iLenCell.getStringCellValue());
					}

					// 保存
					if (!hasExistPart(parentId, partIdentify)) {// 同一节点下,不可能存在相同编码的子节点
						// 层级下的value值限定了编码的长度
						if (iLen > partIdentify.length() || iLen == partIdentify.length()) {
							Part part = new Part();
							part.setEventShow(true);
							part.setGridShow(true);
							part.setMemo("excel 导入数据");
							part.setPartIdentify(partIdentify);
							part.setPartLevel(option);
							part.setPartName(partName);
							part.setPartOrder(partOrder);
							part.setPartParent(parentId);
							part.setPartShow(true);
							part.setPartType(type);
							part.setUserShow(true);
							part.setIconAddress(addr);
							partService.getRepository().save(part);
							// 存完之后再进行排序
							partService.setPartOrder(parentId);
						} else {
							return MsgHelper.failed().put("msg", "第 " + nowRow + " 行编码位数不对 ");
						}
					} else {
						return MsgHelper.failed().put("msg", "第 " + nowRow + " 行数据编码与已有数据编码冲突 ");
					}

				}

			} catch (Exception e) {
				e.printStackTrace();
				return MsgHelper.failed().put("msg", "第 " + nowRow + " 行数据错误 ");

			}
		}
		return MsgHelper.success();
	}

	@RequestMapping(value = "/downEventType/{eventTypeId}", method = RequestMethod.POST)
	public void downEventType(@PathVariable("eventTypeId") String eventTypeId, HttpServletResponse response) {
		String fileName = "downloadE.xls";
		HSSFWorkbook wb = null;
		OutputStream outputStream = null;
		EventType eventType = eventTypeService.getRepository().findOne(eventTypeId);
		try {
			// 1 创建workbook
			wb = new HSSFWorkbook();
			// 2 创建sheet
			HSSFSheet sheet = wb.createSheet("事件类型模板");
			// 3 创建表头行
			HSSFRow row = sheet.createRow(0);
			// 4 创建单元格
			row.createCell(0).setCellValue("事件名称");
			row.createCell(1).setCellValue("事件编码");
			row.createCell(2).setCellValue("事件顺序");
			row.createCell(3).setCellValue("父级编号");
			row.createCell(4).setCellValue("事件权重");
			row.createCell(5).setCellValue("处理时限");
			row.createCell(6).setCellValue("接受时限");
			row.createCell(7).setCellValue("首次奖励积分");
			row.createCell(8).setCellValue("累计奖励积分");
			row.createCell(9).setCellValue("备注");
			row.createCell(10).setCellValue("组织层级");
			row.createCell(11).setCellValue("编码位数限定");
			row.createCell(12).setCellValue("图标地址");
			if (eventType == null) {
				// 初始化50行数据
				Option o = optionService.getRepository().findByGroupAndTitle("事件层级", "一级").get(0);
				for (int i = 1; i <= 50; i++) {
					HSSFRow row2 = sheet.createRow(i);
					row2.createCell(3).setCellValue("0");
					row2.createCell(10).setCellValue("一级");
					row2.createCell(11).setCellValue(o.getValue());
				}
			} else {
				// 下一个层级
				String currentLevelValue = eventType.getEventLevel().getExtended1();
				int nextLevelValueInt = Integer.parseInt(currentLevelValue) + 1;
				Option option = super.getLevelOption(nextLevelValueInt, optionService, "事件层级");
				// 初始化50行数据
				for (int i = 1; i <= 50; i++) {
					HSSFRow row2 = sheet.createRow(i);
					row2.createCell(3).setCellValue("[" + eventTypeId + "]" + eventType.getEventName());
					row2.createCell(10).setCellValue(option.getTitle());
					row2.createCell(11).setCellValue(Integer.parseInt(option.getValue()));
				}
			}
			// 将文件写入流
			outputStream = response.getOutputStream();
			response.setCharacterEncoding("utf-8");
			response.setContentType("multipart/form-data");
			response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
			wb.write(outputStream);
			outputStream.flush();
			outputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (outputStream != null) {
					outputStream.close();
					outputStream = null;
				}

				if (wb != null) {
					wb.close();
					wb = null;
				}

			} catch (IOException e) {

				e.printStackTrace();
			}
		}

	}

	/**
	 * 下载组织模板
	 * 
	 * @param hierarchyId
	 * @param response
	 */
	@RequestMapping(value = "/downHierarchy/{hierarchyId}", method = RequestMethod.POST)
	public void downHierarchy(@PathVariable("hierarchyId") String hierarchyId, HttpServletResponse response) {
		String fileName = "downloadH.xls";
		HSSFWorkbook wb = null;
		OutputStream outputStream = null;
		Hierarchy hierarchy = hierarchyService.getRepository().findOne(hierarchyId);// 树的根节点id为0
		try {
			// 1 创建workbook
			wb = new HSSFWorkbook();
			// 2 创建sheet
			HSSFSheet sheet = wb.createSheet("组织模板");
			// 3 创建表头行
			HSSFRow row = sheet.createRow(0);
			// 4 创建单元格
			row.createCell(0).setCellValue("组织名称");
			row.createCell(1).setCellValue("组织编码");
			row.createCell(2).setCellValue("组织顺序");
			row.createCell(3).setCellValue("父级编号");
			row.createCell(4).setCellValue("组织电话");
			row.createCell(5).setCellValue("组织基本考评分数");
			row.createCell(6).setCellValue("组织基本考评权重");
			row.createCell(7).setCellValue("组织层级");
			row.createCell(8).setCellValue("图标地址");
			row.createCell(9).setCellValue("备注");
			row.createCell(10).setCellValue("编码位数限定");
			if (hierarchy == null) {
				// 初始化50行数据
				Option o = optionService.getRepository().findByGroupAndTitle("组织层级", "一级").get(0);
				for (int i = 1; i <= 50; i++) {
					HSSFRow row2 = sheet.createRow(i);
					row2.createCell(3).setCellValue("0");
					row2.createCell(7).setCellValue("一级");
					row2.createCell(10).setCellValue(o.getValue());
				}
			} else {
				// 下一个层级
				String currentLevelValue = hierarchy.getGroupLevel().getExtended1();
				int nextLevelValueInt = Integer.parseInt(currentLevelValue) + 1;
				Option option = super.getLevelOption(nextLevelValueInt, optionService, "组织层级");
				// 初始化50行数据
				for (int i = 1; i <= 50; i++) {
					HSSFRow row2 = sheet.createRow(i);
					row2.createCell(3).setCellValue("[" + hierarchyId + "]" + hierarchy.getGroupName());
					row2.createCell(7).setCellValue(option.getTitle());
					row2.createCell(10).setCellValue(Integer.parseInt(option.getValue()));
				}
			}
			// 将文件写入流
			outputStream = response.getOutputStream();
			response.setCharacterEncoding("utf-8");
			response.setContentType("multipart/form-data");
			response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
			wb.write(outputStream);
			outputStream.flush();
			outputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (outputStream != null) {
					outputStream.close();
					outputStream = null;
				}

				if (wb != null) {
					wb.close();
					wb = null;
				}

			} catch (IOException e) {

				e.printStackTrace();
			}

		}
	}

	/**
	 * 下载区域树模板
	 * 
	 * @param divisionId
	 *            区域id
	 * @param response
	 */
	@RequestMapping(value = "/downDivision/{divisionId}", method = RequestMethod.POST)
	public void downDivision(@PathVariable("divisionId") String divisionId, HttpServletResponse response) {
		String fileName = "downloadD.xls";
		HSSFWorkbook wb = null;
		OutputStream outputStream = null;
		Division division = divisionService.getRepository().findOne(divisionId);// 树的根节点id为0
		try {
			// 1 创建workbook
			wb = new HSSFWorkbook();
			// 2 创建sheet
			HSSFSheet sheet = wb.createSheet("区域模板");
			// 3 创建表头行
			HSSFRow row = sheet.createRow(0);
			// 4 创建单元格
			row.createCell(0).setCellValue("区域名称");
			row.createCell(1).setCellValue("区域编码");
			row.createCell(2).setCellValue("区域顺序");
			row.createCell(3).setCellValue("父级编号");
			row.createCell(4).setCellValue("区域层级");
			row.createCell(5).setCellValue("图标地址");
			row.createCell(6).setCellValue("备注");
			row.createCell(7).setCellValue("编码位数限定");
			if (division == null) {
				// 初始化50行数据
				Option o = optionService.getRepository().findByGroupAndTitle("部件层级", "一级").get(0);
				for (int i = 1; i <= 50; i++) {
					HSSFRow row2 = sheet.createRow(i);
					row2.createCell(3).setCellValue("0");
					row2.createCell(4).setCellValue("一级");
					row2.createCell(7).setCellValue(o.getValue());
				}
			} else {
				// 下一个层级
				String currentLevelValue = division.getDivisionLevel().getExtended1();
				int nextLevelValueInt = Integer.parseInt(currentLevelValue) + 1;
				Option option = super.getLevelOption(nextLevelValueInt, optionService, "区域层级");
				// 初始化50行数据
				for (int i = 1; i <= 50; i++) {
					HSSFRow row2 = sheet.createRow(i);
					row2.createCell(3).setCellValue("[" + divisionId + "]" + division.getDivisionName());
					row2.createCell(4).setCellValue(option.getTitle());
					row2.createCell(7).setCellValue(Integer.parseInt(option.getValue()));
				}
			}

			// 将文件写入流
			outputStream = response.getOutputStream();
			response.setCharacterEncoding("utf-8");
			response.setContentType("multipart/form-data");
			response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
			wb.write(outputStream);
			outputStream.flush();
			outputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (outputStream != null) {
					outputStream.close();
					outputStream = null;
				}

				if (wb != null) {
					wb.close();
					wb = null;
				}

			} catch (IOException e) {

				e.printStackTrace();
			}

		}

	}

	/**
	 * 下载部件类型表
	 * 
	 * @param response
	 * @param request
	 */
	@RequestMapping(value = "/downPart/{partId}", method = RequestMethod.POST)
	public void downPart(@PathVariable("partId") String partId, HttpServletResponse response) {
		String fileName = "downloadP.xls";
		HSSFWorkbook wb = null;
		OutputStream outputStream = null;

		// 数据准备
		Part part = partService.getRepository().findOne(partId);// 树的根节点为0

		try {

			// 生成EXCEL表
			// 1 创建workbook
			wb = new HSSFWorkbook();
			// 2 创建sheet
			HSSFSheet sheet = wb.createSheet("部件类型");
			// 3 创建表头行
			HSSFRow row = sheet.createRow(0);
			// 4 创建单元格
			HSSFCell cell0 = row.createCell(0);
			cell0.setCellValue("部件名称");
			HSSFCell cell1 = row.createCell(1);
			cell1.setCellValue("部件编码");
			HSSFCell cell2 = row.createCell(2);
			cell2.setCellValue("部件顺序");
			HSSFCell cell3 = row.createCell(3);
			cell3.setCellValue("父级编号");
			HSSFCell cell4 = row.createCell(4);
			cell4.setCellValue("部件分类");
			HSSFCell cell5 = row.createCell(5);
			cell5.setCellValue("部件层级");
			HSSFCell cell6 = row.createCell(6);
			cell6.setCellValue("图标地址");
			HSSFCell cell7 = row.createCell(7);
			cell7.setCellValue("编码字符限定个数");
			if (part == null) {// partId=0 即树的根节点
				// 下载的模板是部件类型的层级为一级的模板,其parentId都为0
				// 初始化50行数据
				Option o = optionService.getRepository().findByGroupAndTitle("部件层级", "一级").get(0);
				for (int i = 1; i <= 50; i++) {
					HSSFRow row2 = sheet.createRow(i);
					row2.createCell(3).setCellValue("0");
					row2.createCell(5).setCellValue("一级");

					row2.createCell(7).setCellValue(o.getValue());
				}
			} else {
				// 下一个层级
				String currentLevelValue = part.getPartLevel().getExtended1();
				int nextLevelValueInt = Integer.parseInt(currentLevelValue) + 1;
				Option option = super.getLevelOption(nextLevelValueInt, optionService, "部件层级");
				// 初始化100行数据
				for (int i = 1; i <= 50; i++) {
					HSSFRow row2 = sheet.createRow(i);
					row2.createCell(3).setCellValue("[" + partId + "]" + part.getPartName());
					row2.createCell(5).setCellValue(option.getTitle());
					row2.createCell(7).setCellValue(Integer.parseInt(option.getValue()));
				}
			}
			// 初始化部件分类[下拉框选择]
			List<Option> os = optionService.getRepository().findByGroup("部件类别");
			String[] types = null;
			int len = 0;
			if (os.size() > 0 && os != null) {
				types = new String[os.size()];
				for (Option o : os) {
					types[len++] = o.getTitle();
				}
			}
			CellRangeAddressList regions = new CellRangeAddressList(1, 50, 4, 4);
			DVConstraint constraint = DVConstraint.createExplicitListConstraint(types);
			HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint);
			sheet.addValidationData(dataValidation);
			// 将文件写入流
			outputStream = response.getOutputStream();
			response.setCharacterEncoding("utf-8");
			response.setContentType("multipart/form-data");
			response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
			wb.write(outputStream);
			outputStream.flush();
			outputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (outputStream != null) {
					outputStream.close();
					outputStream = null;
				}

				if (wb != null) {
					wb.close();
					wb = null;
				}

			} catch (IOException e) {

				e.printStackTrace();
			}

		}

	}

	private boolean hasExistEventType(String parentId, String eventIdentify) {
		List<EventType> types = eventTypeService.findByParentId(parentId);
		List<String> list = new ArrayList<>();
		if (types != null && types.size() > 0) {
			for (EventType e : types) {
				list.add(e.getEventIdentify());
			}
		}
		if (list.size() == 0) {
			return false;
		} else {
			if (list.contains(eventIdentify)) {
				return true;
			} else {
				return false;
			}
		}
	}

	private boolean hasExistDivision(String parentId, String divisionIdentify) {
		List<Division> divisions = divisionService.findByParentId(parentId);
		List<String> list = new ArrayList<>();
		if (divisions != null && divisions.size() > 0) {

			for (Division d : divisions) {
				list.add(d.getDivisionIdentify());
			}
		}
		if (list.size() == 0) {
			return false;
		} else {
			if (list.contains(divisionIdentify)) {
				return true;
			} else {
				return false;
			}
		}

	}

	private boolean hasExistHierarchy(String parentId, String groupIdentify) {
		List<Hierarchy> hierarchies = hierarchyService.findByParentId(parentId);
		List<String> list = new ArrayList<>();
		if (hierarchies != null && hierarchies.size() > 0) {
			for (Hierarchy h : hierarchies) {
				list.add(h.getGroupIdentify());
			}
		}
		if (list.size() == 0) {
			return false;
		} else {
			if (list.contains(groupIdentify)) {
				return true;
			} else {
				return false;
			}
		}
	}

	private boolean hasExistPart(String parentId, String partIdentify) {
		List<Part> parts = partService.findByParentId(parentId);
		List<String> list = new ArrayList<>();
		if (parts.size() > 0 && parts != null) {
			for (Part part : parts) {
				list.add(part.getPartIdentify());
			}
		}
		if (list.size() == 0) {
			return false;
		} else {
			if (list.contains(partIdentify)) {
				return true;
			} else {
				return false;
			}
		}
	}

	private boolean isRightFile(MultipartFile file) {
		String fileName = file.getOriginalFilename();
		return fileName != null && !"".equals(fileName) && (fileName.endsWith(".xlsx") || fileName.endsWith(".xls"));
	}

	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView index(ModelAndView modelAndView) {
		modelAndView = createLayoutView("doc/index");
		return modelAndView;
	}
}
